<template>
  <div class="app-container">
    <!-- 操作区域 -->
    <div class="operation-container">
      <el-button type="success" icon="el-icon-refresh" @click="refreshData">
        刷新数据
      </el-button>
    </div>

    <!-- 批次列表 -->
    <div class="batch-list-container">
      <div v-if="loading" class="loading-state">
        <i class="el-icon-loading" />
        <p>加载中...</p>
      </div>
      <div v-else-if="batchList.length === 0" class="empty-state">
        <i class="el-icon-document" />
        <p>暂无批次数据</p>
      </div>

      <div v-else class="batch-cards">
        <div
          v-for="(batch, index) in batchList"
          :key="index"
          class="batch-card"
        >
          <div class="batch-header">
            <h3>批次 #{{ batch.batch }}</h3>
            <div class="batch-actions">
              <el-button size="mini" type="primary" @click="generateScheme(batch, index)">
                生成方案
              </el-button>
              <el-button size="mini" type="text" @click="viewBatchDetails(batch)">
                查看详情
              </el-button>
              <el-button size="mini" type="text" @click="deleteBatch(index)">
                删除
              </el-button>
            </div>
          </div>

          <div class="batch-content">
            <div class="batch-info">
              <span class="info-item">
                <i class="el-icon-trophy" />
                赛事数量: {{ batch.match_count }}
              </span>
              <span class="info-item">
                <i class="el-icon-time" />
                创建时间: {{ formatTime(new Date(batch.create_time)) }}
              </span>
              <span class="info-item status-item">
                <i :class="getStatusIcon(batch.status)" />
                执行状态: <span :class="getStatusClass(batch.status)">{{ getStatusText(batch.status) }}</span>
              </span>
            </div>

            <div class="matches-preview">
              <div
                v-for="(match, matchIndex) in batch.matches.slice(0, 3)"
                :key="matchIndex"
                class="match-preview"
              >
                <div class="match-teams">
                  {{ match.home_team_name }} vs {{ match.away_team_name }}
                </div>
                <div class="match-competition">
                  {{ match.competition_name }}
                </div>
                <div class="match-sport-type">
                  <span :class="getSportTypeClass(match.type)">
                    <i :class="getSportTypeIcon(match.type)" />
                    {{ getSportTypeName(match.type) }}
                  </span>
                </div>
                <div class="match-prediction">
                  {{ match.prediction_type_name }}
                </div>
                <div v-if="match.msg" class="match-msg">
                  <i class="el-icon-info" />
                  执行结果: {{ match.msg }}
                </div>
              </div>
              <div v-if="batch.matches.length > 3" class="more-matches">
                还有 {{ batch.matches.length - 3 }} 场比赛...
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 专家选择方式对话框 -->
    <el-dialog
      title="选择专家方式"
      :visible.sync="expertSelectionDialogVisible"
      width="400px"
      :before-close="handleCloseExpertSelection"
    >
      <div class="expert-selection-container">
        <div class="selection-options">
          <el-radio-group v-model="expertSelectionType">
            <el-radio label="all">使用全部专家</el-radio>
            <el-radio label="partial">选择部分专家</el-radio>
          </el-radio-group>
        </div>
        <div class="selection-description">
          <p v-if="expertSelectionType === 'all'">
            <i class="el-icon-info" />
            将使用所有可用的专家来生成方案
          </p>
          <p v-if="expertSelectionType === 'partial'">
            <i class="el-icon-info" />
            将打开专家选择器，您可以手动选择特定的专家
          </p>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleCloseExpertSelection">取消</el-button>
        <el-button type="primary" @click="handleConfirmExpertSelection">
          确认
        </el-button>
      </div>
    </el-dialog>

    <!-- 专家选择弹窗 -->
    <ExpertSelectorDialog
      :visible.sync="expertSelectorDialogVisible"
      @confirm="handleExpertSelectConfirm"
    />

    <!-- 生成方案配置对话框 -->
    <el-dialog
      title="生成方案配置"
      :visible.sync="schemeConfigDialogVisible"
      width="500px"
      :before-close="handleCloseSchemeConfig"
    >
      <div class="scheme-config-form">
        <el-form :model="schemeConfig" label-width="120px">
          <el-form-item label="期望方案数量:">
            <el-input-number
              v-model="schemeConfig.maxCombinations"
              :min="1"
              :max="100"
              :step="1"
              style="width: 200px;"
              placeholder="请输入期望方案数量"
            />
            <div class="form-tip">
              建议设置1-10个方案，过多方案可能影响生成速度
            </div>
          </el-form-item>
          <el-form-item label="期望二串一数量:">
            <el-input-number
              v-model="schemeConfig.maxShuangCombinations"
              :min="0"
              :max="100"
              :step="1"
              style="width: 200px;"
              placeholder="请输入期望二串一数量"
            />
            <div class="form-tip">
              设置期望的二串一方案数量，默认为0
            </div>
          </el-form-item>
          <el-form-item label="期望三串一数量:">
            <el-input-number
              v-model="schemeConfig.maxSanCombinations"
              :min="0"
              :max="100"
              :step="1"
              style="width: 200px;"
              placeholder="请输入期望三串一数量"
            />
            <div class="form-tip">
              设置期望的三串一方案数量，默认为0
            </div>
          </el-form-item>
          <el-form-item label="批次信息:">
            <div class="batch-info-display">
              <p><strong>批次号:</strong> {{ selectedBatchForConfig && selectedBatchForConfig.batch }}</p>
              <p><strong>比赛数量:</strong> {{ selectedBatchForConfig && selectedBatchForConfig.match_count }} 场</p>
              <p><strong>创建时间:</strong> {{ selectedBatchForConfig ? formatTime(new Date(selectedBatchForConfig.create_time)) : '' }}</p>
            </div>
          </el-form-item>
        </el-form>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleCloseSchemeConfig">取消</el-button>
        <el-button type="primary" :loading="generating" @click="confirmGenerateScheme">
          {{ generating ? '生成中...' : '确认生成' }}
        </el-button>
      </div>
    </el-dialog>

    <!-- 批次详情对话框 -->
    <el-dialog
      title="批次详情"
      :visible.sync="detailDialogVisible"
      width="80%"
      :before-close="handleCloseDetail"
    >
      <div v-if="tempSelectedBatch" class="batch-detail">
        <div class="detail-header">
          <h4>批次信息</h4>
          <p>批次号: {{ tempSelectedBatch.batch }} | 共 {{ tempSelectedBatch.match_count }} 场比赛 | 执行状态: <span :class="getStatusClass(tempSelectedBatch.status)">{{ getStatusText(tempSelectedBatch.status) }}</span></p>
        </div>

        <div class="matches-detail">
          <div
            v-for="(match, index) in tempSelectedBatch.matches"
            :key="index"
            class="match-detail-card"
          >
            <div class="match-header" style="display: flex; justify-content: space-between; align-items: center;">
              <div>
                <div class="match-teams">
                  <span class="home-team">{{ match.home_team_name }}</span>
                  <span class="vs">vs</span>
                  <span class="away-team">{{ match.away_team_name }}</span>
                </div>
                <div class="match-competition">{{ match.competition_name }}</div>
                <div class="match-sport-type">
                  <span :class="getSportTypeClass(match.type)">
                    <i :class="getSportTypeIcon(match.type)" />
                    {{ getSportTypeName(match.type) }}
                  </span>
                </div>
              </div>
              <el-button type="text" size="mini" icon="el-icon-delete" @click="removeTempMatch(index)">删除(临时)</el-button>
            </div>

            <div class="match-prediction-info">
              <div class="prediction-type">
                预测类型: {{ match.prediction_type_name }}
              </div>
              <div class="selected-odds">
                <span class="odds-label">选中赔率:</span>
                <div class="odds-list">
                  <span
                    v-for="(odds, oddsIndex) in match.selected_odds"
                    :key="oddsIndex"
                    class="odds-item"
                  >
                    {{ odds.label }}({{ odds.value }})
                  </span>
                </div>
              </div>
              <div v-if="match.msg" class="match-msg">
                <i class="el-icon-info" />
                执行结果: {{ match.msg }}
              </div>
            </div>
          </div>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleCloseDetail">关闭</el-button>
        <el-button type="primary" @click="generateSchemeFromDetail">生成方案</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { piciList, piciDel, zhuanjiaList } from '../../../libs/api'
import axios from 'axios'
import ExpertSelectorDialog from '@/components/ExpertSelectorDialog.vue'

export default {
  name: 'BatchManagement',
  components: {
    ExpertSelectorDialog
  },
  data() {
    return {
      batchList: [],
      detailDialogVisible: false,
      selectedBatch: null,
      tempSelectedBatch: null,
      loading: false,
      // 专家选择相关
      expertSelectionDialogVisible: false,
      expertSelectorDialogVisible: false,
      expertSelectionType: 'all', // 'all' 或 'partial'
      selectedExperts: [], // 用户选择的专家列表
      // 生成方案配置对话框相关
      schemeConfigDialogVisible: false,
      selectedBatchForConfig: null,
      selectedBatchIndex: null,
      generating: false,
      schemeConfig: {
        maxCombinations: 2, // 期望方案数量，默认为2
        maxShuangCombinations: 0, // 期望的二串一数量，默认为0
        maxSanCombinations: 0 // 期望的三串一方案数量，默认为0
      }
    }
  },
  created() {
    this.loadBatchData()
  },
  methods: {
    // 加载批次数据
    loadBatchData() {
      this.loading = true
      piciList({}).then(res => {
        console.log('获取批次列表:', res)
        if (res.data && res.data) {
          // 处理新的数据结构
          this.batchList = res.data.map(batch => {
            // 解析每个比赛的selected_odds JSON字符串
            const processedMatches = batch.matches.map(match => ({
              ...match,
              selected_odds: this.parseSelectedOdds(match.selected_odds)
            }))

            return {
              ...batch,
              matches: processedMatches
            }
          })
          console.log('处理后的批次数据:', this.batchList)
        } else {
          this.batchList = []
        }
        this.loading = false
      }).catch(error => {
        console.error('获取批次列表失败:', error)
        this.$message.error('获取批次列表失败')
        this.loading = false
        // 如果API失败，使用模拟数据
        this.batchList = [
          {
            'batch': 41023,
            'match_count': 2,
            'status': 1, // 执行成功
            'matches': [
              {
                'id': 15,
                'batch': 41023,
                'match_id': 4026675,
                'competition_name': '美职联',
                'competition_id': '26',
                'home_team_name': '温哥华白浪',
                'home_team_id': 10629,
                'away_team_name': '波特兰伐木者',
                'away_team_id': 10630,
                'type': 1, // 足球
                'prediction_type': '1',
                'prediction_type_name': '竞彩',
                'selected_odds': [
                  { 'label': '主胜', 'value': '1.49', 'is_recommend': false },
                  { 'label': '平局', 'value': '4.10', 'is_recommend': false }
                ],
                'match_time': '1758767400',
                'created_at': '2025-09-25 09:59:48',
                'status': 0,
                'msg': null
              }
            ],
            'create_time': '2025-09-25 09:59:48'
          },
          {
            'batch': 41024,
            'match_count': 1,
            'status': 3, // 执行中
            'matches': [
              {
                'id': 16,
                'batch': 41024,
                'match_id': 4026676,
                'competition_name': 'NBA',
                'competition_id': '1',
                'home_team_name': '湖人',
                'home_team_id': 1001,
                'away_team_name': '勇士',
                'away_team_id': 1002,
                'type': 2, // 篮球
                'prediction_type': '2',
                'prediction_type_name': '让分',
                'selected_odds': [
                  { 'label': '主胜', 'value': '2.10', 'is_recommend': true }
                ],
                'match_time': '1758767500',
                'created_at': '2025-09-25 10:00:00',
                'status': 0,
                'msg': null
              }
            ],
            'create_time': '2025-09-25 10:00:00'
          },
          {
            'batch': 41025,
            'match_count': 3,
            'status': 2, // 执行失败
            'matches': [
              {
                'id': 17,
                'batch': 41025,
                'match_id': 4026677,
                'competition_name': '西甲',
                'competition_id': '2',
                'home_team_name': '皇马',
                'home_team_id': 2001,
                'away_team_name': '巴萨',
                'away_team_id': 2002,
                // 没有 type 字段，应该显示为足球
                'prediction_type': '1',
                'prediction_type_name': '竞彩',
                'selected_odds': [
                  { 'label': '平局', 'value': '3.20', 'is_recommend': false }
                ],
                'match_time': '1758767600',
                'created_at': '2025-09-25 10:01:00',
                'status': 0,
                'msg': null
              }
            ],
            'create_time': '2025-09-25 10:01:00'
          },
          {
            'batch': 41026,
            'match_count': 1,
            'status': 0, // 未执行
            'matches': [
              {
                'id': 18,
                'batch': 41026,
                'match_id': 4026678,
                'competition_name': '德甲',
                'competition_id': '3',
                'home_team_name': '拜仁',
                'home_team_id': 3001,
                'away_team_name': '多特',
                'away_team_id': 3002,
                'prediction_type': '3',
                'prediction_type_name': '大小球',
                'selected_odds': [
                  { 'label': '大球', 'value': '1.85', 'is_recommend': true }
                ],
                'match_time': '1758767700',
                'created_at': '2025-09-25 10:02:00',
                'status': 0,
                'msg': null
              }
            ],
            'create_time': '2025-09-25 10:02:00'
          }
        ]
      })
    },

    // 解析selected_odds JSON字符串
    parseSelectedOdds(oddsString) {
      try {
        if (typeof oddsString === 'string') {
          return JSON.parse(oddsString)
        }
        return oddsString || []
      } catch (error) {
        console.error('解析selected_odds失败:', error)
        return []
      }
    },

    // 打开生成方案配置对话框
    generateScheme(batch, batchIndex) {
      this.selectedBatchForConfig = batch
      this.selectedBatchIndex = batchIndex
      this.expertSelectionType = 'all' // 重置为默认值
      // 不清空selectedExperts，保持之前的选择状态
      this.expertSelectionDialogVisible = true
    },

    // 处理专家选择方式确认
    handleConfirmExpertSelection() {
      if (this.expertSelectionType === 'all') {
        // 使用全部专家，直接打开配置对话框
        this.expertSelectionDialogVisible = false
        this.openSchemeConfigDialog()
      } else if (this.expertSelectionType === 'partial') {
        // 选择部分专家，打开专家选择器
        this.expertSelectionDialogVisible = false
        this.expertSelectorDialogVisible = true
      }
    },

    // 关闭专家选择方式对话框
    handleCloseExpertSelection() {
      this.expertSelectionDialogVisible = false
      this.selectedBatchForConfig = null
      this.selectedBatchIndex = null
      // 不清空selectedExperts，保持选择状态
    },

    // 专家选择确认回调
    handleExpertSelectConfirm(selectedExperts) {
      this.selectedExperts = selectedExperts
      this.openSchemeConfigDialog()
    },

    // 打开方案配置对话框
    openSchemeConfigDialog() {
      this.schemeConfig.maxCombinations = 2 // 重置为默认值
      this.schemeConfig.maxShuangCombinations = 0 // 重置为默认值
      this.schemeConfig.maxSanCombinations = 0 // 重置为默认值
      this.schemeConfigDialogVisible = true
    },

    // 确认生成方案
    async confirmGenerateScheme() {
      if (!this.selectedBatchForConfig) {
        this.$message.error('批次信息不存在')
        return
      }

      if (!this.schemeConfig.maxCombinations || this.schemeConfig.maxCombinations < 1) {
        this.$message.error('请输入有效的期望方案数量')
        return
      }

      this.generating = true
      this.schemeConfigDialogVisible = false

      // 显示加载状态
      const loading = this.$loading({
        lock: true,
        text: '正在生成方案...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })

      try {
        // 根据选择方式获取专家数据
        let experts = []

        if (this.expertSelectionType === 'all') {
          // 使用全部专家
          const expertResponse = await zhuanjiaList({
            page: 1,
            page_size: 100 // 获取所有专家
          })
          experts = expertResponse.data.data || []
          console.log('使用全部专家:', experts)
        } else if (this.expertSelectionType === 'partial' && this.selectedExperts.length > 0) {
          // 使用选择的专家
          experts = this.selectedExperts.map(item => ({
            ...item,
            id: item.expert_id
          }))
          console.log('使用选择的专家:', experts)
        } else {
          this.$message.error('请选择专家')
          return
        }

        // 准备请求数据
        const requestData = {
          experts: experts.map(item => {
            return {
              ...item,
              id: item.expert_id
            }
          }), // 使用获取到的专家数据
          matches: this.selectedBatchForConfig.matches.map(item => {
            return {
              ...item,
              prediction_type_name: item.type === 2 ? '让分' : item.prediction_type_name
            }
          }),
          maxCombinations: this.schemeConfig.maxCombinations, // 使用用户设置的期望方案数量
          maxShuangCombinations: this.schemeConfig.maxShuangCombinations, // 期望的二串一数量
          maxSanCombinations: this.schemeConfig.maxSanCombinations, // 期望的三串一方案数量
          enableAnalysis: true,
          batch: this.selectedBatchForConfig.batch
        }

        // return

        // 创建新的axios实例请求本地接口
        const localAxios = axios.create({
          // baseURL: 'http://192.168.2.25:7671',
          baseURL: 'https://expert.zctj16888.com',
          timeout: 2000000, // 30秒超时
          headers: {
            'Content-Type': 'application/json'
          }
        })

        // 调用本地接口
        const res = await localAxios.post('/api/assign-and-analyze-async', requestData)

        loading.close()
        this.generating = false
        console.log('生成方案响应:', res.data)

        if (res.data.success || res.data.code === 1) {
          this.$message.success(`批次 #${this.selectedBatchForConfig.batch} 的方案生成成功`)
          this.refreshData()
        } else {
          this.$message.error(res.data.message || res.data.msg || '方案生成失败')
        }
      } catch (error) {
        loading.close()
        this.generating = false
        console.error('生成方案失败:', error)

        if (error.response) {
          // 服务器返回了错误状态码
          this.$message.error(`请求失败: ${error.response.status} - ${error.response.data?.message || error.response.statusText}`)
        } else if (error.request) {
          // 请求已发出但没有收到响应
          this.$message.error('无法连接到本地服务器，请确保服务器在 http://192.168.2.25:3000 运行')
        } else {
          // 其他错误
          this.$message.error('生成方案失败，请重试')
        }
      }
    },

    // 关闭生成方案配置对话框
    handleCloseSchemeConfig() {
      this.schemeConfigDialogVisible = false
      this.selectedBatchForConfig = null
      this.selectedBatchIndex = null
      this.generating = false
      // 不清空selectedExperts，保持选择状态
    },

    // 刷新数据
    refreshData() {
      this.loadBatchData()
      this.$message.success('数据已刷新')
    },

    // 查看批次详情
    viewBatchDetails(batch) {
      this.selectedBatch = batch
      // 深拷贝一份用于弹窗内的临时展示和临时删除
      this.tempSelectedBatch = JSON.parse(JSON.stringify(batch))
      // 记录当前批次在列表中的索引
      this.selectedBatchIndex = this.batchList.findIndex(b => b.batch === batch.batch)
      this.detailDialogVisible = true
    },

    // 删除批次
    deleteBatch(index) {
      const batch = this.batchList[index]
      this.$confirm('确定要删除这个批次吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 调用删除API
        piciDel({
          batch: batch.batch
        }).then(res => {
          console.log('删除批次响应:', res)
          if (res.code === 1) {
            // 删除成功，从列表中移除
            this.batchList.splice(index, 1)
            this.$message.success('删除成功')
          } else {
            this.$message.error(res.msg || '删除失败')
          }
        }).catch(error => {
          console.error('删除批次失败:', error)
          this.$message.error('删除失败，请重试')
        })
      }).catch(() => {
        this.$message.info('已取消删除')
      })
    },

    // 关闭详情对话框
    handleCloseDetail() {
      this.detailDialogVisible = false
      this.selectedBatch = null
      this.tempSelectedBatch = null
    },

    // 临时从弹窗列表中移除某场比赛（不调接口）
    removeTempMatch(index) {
      if (!this.tempSelectedBatch) return
      this.tempSelectedBatch.matches.splice(index, 1)
      this.tempSelectedBatch.match_count = this.tempSelectedBatch.matches.length
    },

    // 从批次详情弹窗触发生成方案，使用临时列表
    generateSchemeFromDetail() {
      if (!this.tempSelectedBatch) {
        this.$message.error('没有可用的批次信息')
        return
      }
      // 使用原始批次信息，但替换为弹窗中的临时比赛列表
      const batchForConfig = {
        ...this.selectedBatch,
        matches: this.tempSelectedBatch.matches,
        match_count: this.tempSelectedBatch.matches.length
      }
      const batchIndex = this.selectedBatchIndex != null ? this.selectedBatchIndex : this.batchList.findIndex(b => b.batch === batchForConfig.batch)
      this.generateScheme(batchForConfig, batchIndex)
    },

    // 格式化时间
    formatTime(date) {
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      return `${year}-${month}-${day} ${hours}:${minutes}`
    },

    // 获取状态文本
    getStatusText(status) {
      const statusMap = {
        0: '未执行',
        1: '执行成功',
        2: '执行失败',
        3: '执行中'
      }
      return statusMap[status] || '未知状态'
    },

    // 获取状态图标
    getStatusIcon(status) {
      const iconMap = {
        0: 'el-icon-warning-outline', // 未执行 - 警告图标
        1: 'el-icon-success', // 执行成功 - 成功图标
        2: 'el-icon-error', // 执行失败 - 错误图标
        3: 'el-icon-loading' // 执行中 - 加载图标
      }
      return iconMap[status] || 'el-icon-question'
    },

    // 获取状态样式类
    getStatusClass(status) {
      const classMap = {
        0: 'status-pending', // 未执行 - 灰色
        1: 'status-success', // 执行成功 - 绿色
        2: 'status-error', // 执行失败 - 红色
        3: 'status-running' // 执行中 - 蓝色
      }
      return classMap[status] || 'status-unknown'
    },

    // 生成批次标题
    generateBatchTitle(matchList) {
      if (!matchList || matchList.length === 0) {
        return '暂无赛事'
      }

      const count = matchList.length
      let title = ''

      if (count === 1) {
        title = '单关'
      } else if (count === 2) {
        title = '二串一'
      } else if (count === 3) {
        title = '三串一'
      } else {
        title = `${count}串一`
      }

      // 添加比赛对阵信息
      const matchInfo = matchList.map(match => {
        return `${match.home_team_name} vs ${match.away_team_name}`
      }).join(' | ')

      return `${title} ${matchInfo}`
    },

    // 获取运动类型名称
    getSportTypeName(type) {
      // type = 1 或者没有就是足球，type = 2 就是篮球
      if (type === 2) {
        return '篮球'
      }
      return '足球' // 默认足球，包括 type = 1 或 undefined
    },

    // 获取运动类型图标
    getSportTypeIcon(type) {
      if (type === 2) {
        return 'el-icon-basketball' // 篮球图标
      }
      return 'el-icon-football' // 足球图标
    },

    // 获取运动类型样式类
    getSportTypeClass(type) {
      if (type === 2) {
        return 'sport-type-basketball'
      }
      return 'sport-type-football'
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.operation-container {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}

/* 生成方案配置对话框样式 */
.scheme-config-form {
  padding: 20px 0;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
  line-height: 1.4;
}

.batch-info-display {
  background: #f8f9fa;
  padding: 12px;
  border-radius: 4px;
  border: 1px solid #e9ecef;
}

.batch-info-display p {
  margin: 4px 0;
  font-size: 14px;
  color: #606266;
}

.batch-info-display strong {
  color: #303133;
  font-weight: 500;
}

.dialog-footer {
  text-align: right;
  padding-top: 10px;
}

.batch-list-container {
  min-height: 400px;
}

.loading-state, .empty-state {
  text-align: center;
  padding: 60px 20px;
  color: #999;
}

.loading-state i, .empty-state i {
  font-size: 48px;
  margin-bottom: 16px;
  display: block;
}

.loading-state i {
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.batch-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
  gap: 20px;
}

.batch-card {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  padding: 20px;
  background: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.3s;
}

.batch-card:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.batch-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #f0f0f0;
}

.batch-header h3 {
  margin: 0;
  color: #303133;
  font-size: 18px;
}

.batch-actions {
  display: flex;
  gap: 8px;
}

.batch-info {
  display: flex;
  gap: 20px;
  margin-bottom: 16px;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 4px;
  color: #606266;
  font-size: 14px;
}

.matches-preview {
  max-height: 200px;
  overflow-y: auto;
}

.match-preview {
  padding: 8px 0;
  border-bottom: 1px solid #f5f5f5;
}

.match-preview:last-child {
  border-bottom: none;
}

.match-teams {
  font-weight: 500;
  color: #303133;
  margin-bottom: 4px;
}

.match-competition {
  font-size: 12px;
  color: #909399;
  margin-bottom: 2px;
}

.match-sport-type {
  margin-bottom: 4px;
}

.match-sport-type span {
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.sport-type-football {
  color: #67c23a;
  background: #f0f9ff;
  border: 1px solid #b3e19d;
}

.sport-type-basketball {
  color: #e6a23c;
  background: #fdf6ec;
  border: 1px solid #f5dab1;
}

.match-prediction {
  font-size: 12px;
  color: #409eff;
  background: #ecf5ff;
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-block;
}

.more-matches {
  text-align: center;
  color: #909399;
  font-size: 12px;
  padding: 8px 0;
  font-style: italic;
}

.batch-detail {
  max-height: 600px;
  overflow-y: auto;
}

.detail-header {
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid #e4e7ed;
}

.detail-header h4 {
  margin: 0 0 8px 0;
  color: #303133;
}

.matches-detail {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.match-detail-card {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 16px;
  background: #fafafa;
}

.match-header {
  margin-bottom: 12px;
}

.match-teams {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}

.home-team, .away-team {
  font-weight: 500;
  color: #303133;
}

.vs {
  color: #909399;
  font-size: 12px;
}

.match-competition {
  font-size: 12px;
  color: #606266;
}

.match-sport-type {
  margin-top: 4px;
}

.match-sport-type span {
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.sport-type-football {
  color: #67c23a;
  background: #f0f9ff;
  border: 1px solid #b3e19d;
}

.sport-type-basketball {
  color: #e6a23c;
  background: #fdf6ec;
  border: 1px solid #f5dab1;
}

.match-prediction-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.prediction-type {
  font-size: 14px;
  color: #606266;
}

.selected-odds {
  display: flex;
  align-items: center;
  gap: 8px;
}

.odds-label {
  font-size: 14px;
  color: #606266;
  min-width: 80px;
}

.odds-list {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.odds-item {
  background: #409eff;
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
}

.match-msg {
  font-size: 13px;
  color: #606266;
  margin-top: 8px;
  padding: 6px 10px;
  background: #f4f4f5;
  border-left: 3px solid #909399;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.match-msg i {
  color: #909399;
  font-size: 14px;
}

/* 状态样式 */
.status-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.status-pending {
  color: #909399;
  font-weight: 500;
}

.status-success {
  color: #67c23a;
  font-weight: 500;
}

.status-error {
  color: #f56c6c;
  font-weight: 500;
}

.status-running {
  color: #409eff;
  font-weight: 500;
}

.status-unknown {
  color: #606266;
  font-weight: 500;
}

/* 执行中状态的动画效果 */
.status-running .el-icon-loading {
  animation: rotating 2s linear infinite;
}

/* 专家选择对话框样式 */
.expert-selection-container {
  padding: 20px 0;
}

.selection-options {
  margin-bottom: 20px;
}

.selection-options .el-radio-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.selection-options .el-radio {
  margin-right: 0;
  margin-bottom: 0;
}

.selection-description {
  padding: 15px;
  background: #f8f9fa;
  border-radius: 6px;
  border: 1px solid #e9ecef;
}

.selection-description p {
  margin: 0;
  color: #606266;
  font-size: 14px;
  line-height: 1.5;
}

.selection-description i {
  color: #409eff;
  margin-right: 6px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .batch-cards {
    grid-template-columns: 1fr;
  }

  .batch-info {
    flex-direction: column;
    gap: 8px;
  }

  .match-teams {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .vs {
    display: none;
  }
}
</style>
